home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1989 / 07 / duvanenk.lst next >
File List  |  1989-06-01  |  12KB  |  356 lines

  1. _IMAGE MATHEMATICS_
  2. by Victor Duvanenko
  3.  
  4. [LISTING ONE]
  5.  
  6. /*  Created by Victor J. Duvanenko  10-17-88
  7.     Image addition using the CPU/80386.  The program reads a buffer full of
  8.     pixels from two images, adds their pixels together and stores the result
  9.     back into the second image.
  10. */
  11.  
  12. #include "cmdtypes.h"
  13. #include <stdio.h>
  14. #include <setjmp.h>
  15. #include "const.h"
  16. #include <fcntl.h>
  17.  
  18. #define  DEBUG  0
  19. #define  ADD    1
  20. #define  DRAW   0
  21.  
  22. extern int _fmode;  /* file mode */
  23.  
  24. /* CMD configuration parameters: */
  25. unsigned memseg=0xD000; /* memory segment */
  26. int pbase=0x208;    /* port base */
  27.  
  28. /* entire bitmap expressed as a RECT: */
  29. RECT screen={0,0,XRES-1,YRES-1}; 
  30.  
  31. POINT vertices[3];
  32.  
  33. extern jmp_buf errjmp;
  34. int frame_grab=0;  /* frame/field grab */
  35. int hiquality=0;   /* use high quality image reduction routines? */
  36.  
  37. /* current video parameters */
  38. int hue=101;
  39. int sat=111;
  40. int con=123;
  41. int bri=40;
  42.  
  43. /* Red, green and blue buffers */
  44. unsigned char    red_1[ 640 * 13 ],
  45.                 red_2[ 640 * 13 ],
  46.                 green_1[ 640 * 13 ],
  47.                 green_2[ 640 * 13 ],
  48.                 blue_1[ 640 * 13 ],
  49.                 blue_2[ 640 * 13 ];
  50.  
  51. /*-------------------------------------------------------------------
  52.                         Invocation:  add_blt
  53. ---------------------------------------------------------------------*/
  54. main(argc,argv)
  55. int argc;
  56. char *argv[];
  57. {
  58. register i, tmp, line;
  59. RECT image1;
  60. int        saturate;
  61. unsigned char *r1_p, *r2_p, *g1_p, *g2_p, *b1_p, *b2_p;
  62.  
  63.     cmd_init( 0xD000, 0x208 );
  64.     cmd_display( 2 );
  65.  
  66. #if DRAW
  67.     cmd_clear( 1 );
  68.     cmd_clear( 2 );
  69.     cmd_clear( 3 );
  70.     cmd_text_fgcolor( 127, 127, 127 );
  71.     cmd_text_bgcolor( 0, 0, 0 );
  72.     cmd_line_attrib( 0, 0xffff, 127, 127, 127 );
  73.     cmd_write_string( 1, 10, 1, "First  bitmap." );
  74.     cmd_line( 1, 639,0,  0,479 );
  75.     cmd_line( 1, 0,0,  639,479 );
  76.     cmd_write_string( 2, 20, 1, "Second bitmap." );
  77.     cmd_line( 2, 639,0,  0,479 );
  78.     cmd_line( 2, 0,0,  639,479 );
  79. #endif
  80.  
  81.     saturate = TRUE;
  82.  
  83.     for( line = 0; line < 480; line += 13 )
  84.     {
  85. #if ADD
  86.         r1_p = red_1;
  87.         r2_p = red_2;
  88.         g1_p = green_1;
  89.         g2_p = green_2;
  90.         b1_p = blue_1;
  91.         b2_p = blue_2;
  92.  
  93. #endif
  94.         /* Perform the same operation using the CPU - 80386 in our case. */
  95.         image1.llx = 0;
  96.         image1.lly = line;
  97.         image1.urx = 639;
  98.         image1.ury = line + 12;
  99.         cmd_read_area( 1, &image1, red_1, green_1, blue_1 );
  100.         cmd_read_area( 2, &image1, red_2, green_2, blue_2 );
  101.  
  102. #if ADD
  103.         /* Add all of the pixels together - use pointers for speed. */
  104.         if ( !saturate )
  105.             for( i = 0; i < 640 * 13; i++ )
  106.             {
  107.                 *r2_p++ += *r1_p++;
  108.                 *g2_p++ += *g1_p++;
  109.                 *b2_p++ += *b1_p++;
  110.             }
  111.         else
  112.             for( i = 0; i < 640 * 13; i++, r1_p++, g1_p++, b1_p++ )
  113.             {
  114.                 tmp = (int)( *r2_p ) + (int)( *r1_p );
  115.                 if ( tmp > 255 )    tmp = 255;
  116.                 *r2_p++ = (unsigned char)( tmp );
  117.  
  118.                 tmp = (int)( *g2_p ) + (int)( *g1_p );
  119.                 if ( tmp > 255 )    tmp = 255;
  120.                 *g2_p++ = (unsigned char)( tmp );
  121.  
  122.                 tmp = (int)( *b2_p ) + (int)( *b1_p );
  123.                 if ( tmp > 255 )    tmp = 255;
  124.                 *b2_p++ = (unsigned char)( tmp );
  125.             }
  126. #endif
  127.  
  128.         /* Place them back into bitmap 2 */
  129.         cmd_write_area( 2, &image1, red_2, green_2, blue_2, 0 );
  130.     }
  131.  
  132.     return( 0 );
  133.  
  134. } /* end main */
  135.  
  136.  
  137. [LISTING TWO]
  138.  
  139. /*-------------------------------------------------------------------
  140.   Procedure that is an extension to 'cmd_copy_image'.  It performs
  141.   the image copy with an ADD operation.
  142.   This procedure figures out which of the 3 bitmaps is not being used
  143.   for the operation and uses it for scratch space.  The effected area
  144.   is at the same location as the destination.  The user has to be aware
  145.   of this.
  146. ---------------------------------------------------------------------*/
  147. static void add_blt( from_bm, image, to_bm, to_x, to_y, saturate )
  148. int from_bm;
  149. RECT    *image;
  150. int        to_bm,
  151.         to_x,
  152.         to_y,
  153.         saturate;        /* 1 - saturate, 0 - don't saturate */
  154. {
  155.     register i;
  156.     int        scratch_bm, one_used, two_used, three_used;
  157.     unsigned int mask;
  158.     RECT    to_image,
  159.             to_image1;        /* 1 bpp coordinates */
  160.  
  161.     /* Figure out which bitmap is not used in the operation and use it */
  162.     /* for scratch space.                                              */
  163.     one_used = two_used = three_used = 0;
  164.     if ( from_bm == 1  ||  to_bm == 1 )
  165.         one_used = 1;
  166.     if ( from_bm == 2  ||  to_bm == 2 )
  167.         two_used = 1;
  168.     if ( from_bm == 3  ||  to_bm == 3 )
  169.         three_used = 1;
  170.     if ( !one_used )
  171.         scratch_bm = 1;
  172.     else if ( !two_used )
  173.         scratch_bm = 2;
  174.     else
  175.         scratch_bm = 3;
  176.  
  177.     to_image.llx = to_x;
  178.     to_image.lly = to_y;
  179.     to_image.urx = to_x + ( image->urx - image->llx );
  180.     to_image.ury = to_y + ( image->ury - image->lly );
  181.  
  182.     /* Adjust X only for 8 bpp to 1 bpp conversion */
  183.     to_image1.llx = to_x << 3;
  184.     to_image1.lly = to_y;
  185.     to_image1.urx = (( to_image.urx + 1 ) << 3 ) - 1;
  186.     to_image1.ury = to_image.ury;
  187.  
  188.     /* Place a copy of the destination image in scratch space */
  189.     cmd_copy_image( to_bm, &to_image, scratch_bm, to_x, to_y, 0 );
  190.  
  191.     /* Form the XOR/SUM result, in the destination bitmap */
  192.     cmd_copy_image( from_bm, image, to_bm, to_x, to_y, 1 );
  193.  
  194.     /* Form the AND/CARRY result, in the scratch bitmap   */
  195.     cmd_copy_image( from_bm, image, scratch_bm, to_x, to_y, 2 );
  196.  
  197.     /* Now bit 0 of all pixels is done */
  198.     /* The sum 0 is already in destination bitmap and carry 0 is in AND */
  199.  
  200.     /* We now need to form the sum 1, which is the XOR of bit 1 and carry 0  */
  201.     /* This requires bit 1 of destination bitmap to be XOR'ed with bit 0 of  */
  202.     /* the AND/CARRY bitmap.  The result is placed in the destination.       */
  203.  
  204.     /* This can not be accomplished at 8 bpp, as all operations happen on    */
  205.     /* pixel boundaries - 8 bits.  Therefore, from this point forward we     */
  206.     /* must treat our bitmap as 1 bpp, since this allows single bit          */
  207.     /* manipulation.                                                         */
  208.  
  209.     for( i = 1, mask = 0x0202; i < 8; i++, mask <<= 1 )
  210.     { 
  211.         /* Form the sum of bit i. */;
  212.         cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx - 1, to_image1.lly, 1, mask, 1 );
  213.  
  214.         if (( mask == 0x8080 ) && ( !saturate ))
  215.             break;    /* don't form the cary - done! */
  216.  
  217.         /* Form the carry bit i by first using the carry in and AND'ing */
  218.         /* it with !SUM */
  219.         cmd_wm_copy_image( to_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 6, mask >> 1, 1 );
  220.  
  221.         /* Form the OR part of the carry bit i. */
  222.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx - 1, to_image1.lly, 3, mask, 1 );
  223.     }
  224. #if 0
  225.     /* the old method - took 8 blits */
  226.     /* Saturate the color based on the carry(7). */
  227.     if ( saturate )
  228.         for ( i = 7, mask = 0x0101; i >= 0; i--, mask <<= 1 )
  229.             cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx + i, to_image1.lly, 3, mask, 1 );
  230. #endif
  231.     /* new and faster algorithm - takes only 4 blits */
  232.     if ( saturate )
  233.     {
  234.         /* replicate carry[7] throughout the whole pixel of scratch space */
  235.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 0, 0x4040, 1 );
  236.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 2, to_image1.lly, 0, 0x3030, 1 );
  237.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 4, to_image1.lly, 0, 0x0f0f, 1 );
  238.  
  239.         /* saturate the image all bits at once */
  240.         cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx, to_image1.lly, 3, 0xffff, 1 );
  241.     }
  242.  
  243.     /* Restore modified bitmaps to 8 bpp */
  244.     set_gpbitmap_bpp( to_bm,      8 );
  245.     set_gpbitmap_bpp( scratch_bm, 8 );
  246. }
  247. /*-------------------------------------------------------------------
  248.   Procedure that is an extension to 'cmd_copy_image'.  It performs
  249.   the image copy with an ADD operation.
  250.   This procedure figures out which of the 3 bitmaps is not being used
  251.   for the operation and uses it for scratch space.  The effected area
  252.   is at the same location as the destination.  The user has to be aware
  253.   of this.
  254. ---------------------------------------------------------------------*/
  255. static void sub_blt( from_bm, image, to_bm, to_x, to_y, saturate )
  256. int from_bm;
  257. RECT    *image;
  258. int        to_bm,
  259.         to_x,
  260.         to_y,
  261.         saturate;        /* 1 - saturate, 0 - don't saturate */
  262. {
  263.     register i;
  264.     int        scratch_bm, one_used, two_used, three_used;
  265.     unsigned int mask;
  266.     RECT    to_image,
  267.             to_image1;        /* 1 bpp coordinates */
  268.  
  269.     /* Figure out which bitmap is not used in the operation and use it */
  270.     /* for scratch space.                                              */
  271.     one_used = two_used = three_used = 0;
  272.     if ( from_bm == 1  ||  to_bm == 1 )
  273.         one_used = 1;
  274.     if ( from_bm == 2  ||  to_bm == 2 )
  275.         two_used = 1;
  276.     if ( from_bm == 3  ||  to_bm == 3 )
  277.         three_used = 1;
  278.     if ( !one_used )
  279.         scratch_bm = 1;
  280.     else if ( !two_used )
  281.         scratch_bm = 2;
  282.     else
  283.         scratch_bm = 3;
  284.  
  285.     to_image.llx = to_x;
  286.     to_image.lly = to_y;
  287.     to_image.urx = to_x + ( image->urx - image->llx );
  288.     to_image.ury = to_y + ( image->ury - image->lly );
  289.  
  290.     /* Adjust X only for 8 bpp to 1 bpp conversion */
  291.     to_image1.llx = to_x << 3;
  292.     to_image1.lly = to_y;
  293.     to_image1.urx = (( to_image.urx + 1 ) << 3 ) - 1;
  294.     to_image1.ury = to_image.ury;
  295.  
  296.     /* Place a copy of the destination image in scratch space */
  297.     cmd_copy_image( to_bm, &to_image, scratch_bm, to_x, to_y, 0 );
  298.  
  299.     /* Form the XOR/SUM result, in the destination bitmap */
  300.     cmd_copy_image( from_bm, image, to_bm, to_x, to_y, 1 );
  301.  
  302.     /* Form the AND/CARRY result, in the scratch bitmap   */
  303.     cmd_copy_image( from_bm, image, scratch_bm, to_x, to_y, 6 );
  304.  
  305.     /* Now bit 0 of all pixels is done */
  306.     /* The sum 0 is already in destination bitmap and carry 0 is in AND */
  307.  
  308.     /* We now need to form the sum 1, which is the XOR of bit 1 and carry 0  */
  309.     /* This requires bit 1 of destination bitmap to be XOR'ed with bit 0 of  */
  310.     /* the AND/CARRY bitmap.  The result is placed in the destination.       */
  311.  
  312.     /* This can not be accomplished at 8 bpp, as all operations happen on    */
  313.     /* pixel boundaries - 8 bits.  Therefore, from this point forward we     */
  314.     /* must treat our bitmap as 1 bpp, since this allows single bit          */
  315.     /* manipulation.                                                         */
  316.  
  317.     for( i = 1, mask = 0x0202; i < 8; i++, mask <<= 1 )
  318.     { 
  319.         /* Form the sum of bit i. */;
  320.         cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx - 1, to_image1.lly, 1, mask, 1 );
  321.  
  322.         if (( mask == 0x8080 ) && ( !saturate ))
  323.             break;    /* don't form the cary - done! */
  324.  
  325.         /* Form the carry bit i by first using the carry in and AND'ing */
  326.         /* it with !SUM */
  327.         cmd_wm_copy_image( to_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 2, mask >> 1, 1 );
  328.  
  329.         /* Form the OR part of the carry bit i. */
  330.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx - 1, to_image1.lly, 3, mask, 1 );
  331.     }
  332. #if 0
  333.     /* Saturate the color based on the borrow(7). */
  334.     if ( saturate )
  335.         for ( i = 7, mask = 0x0101; i >= 0; i--, mask <<= 1 )
  336.             cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx + i, to_image1.lly, 6, mask, 1 );
  337. #endif
  338.     /* new and faster algorithm - takes only 4 blits */
  339.     if ( saturate )
  340.     {
  341.         /* replicate carry[7] throughout the whole pixel of scratch space */
  342.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 1, to_image1.lly, 0, 0x4040, 1 );
  343.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 2, to_image1.lly, 0, 0x3030, 1 );
  344.         cmd_wm_copy_image( scratch_bm, &to_image1, scratch_bm, to_image1.llx + 4, to_image1.lly, 0, 0x0f0f, 1 );
  345.  
  346.         /* saturate the image all bits at once */
  347.         cmd_wm_copy_image( scratch_bm, &to_image1, to_bm, to_image1.llx, to_image1.lly, 6, 0xffff, 1 );
  348.     }
  349.  
  350.     /* Restore modified bitmaps to 8 bpp */
  351.     set_gpbitmap_bpp( to_bm,      8 );
  352.     set_gpbitmap_bpp( scratch_bm, 8 );
  353. }
  354.  
  355.  
  356.